package Day_0131.JVM;

/**
 * @author zxc
 * @date 2023/01/31 16:18
 **/
public class HashTable_HashMap {
    public static void main(String[] args) {
        /**
         * HashTable和HashMap的区别联系
         * 1. 出生的版本不一样，Hashtable 出生于 Java 发布的第一版本 JDK 1.0，HashMap 出生于 JDK1.2。
         *
         * 2. 都实现了 Map、Cloneable、Serializable（当前 JDK 版本 1.8）。
         *
         * 3.
         * HashMap 继承的是 AbstractMap，并且 AbstractMap 也实现了 Map 接口。
         * Hashtable 继承Dictionary。
         *
         * 4.线程是否安全
         * （1）Hashtable 中大部分 public 修饰普通方法都是synchronized关键字修饰的，是线程安全的，
         * （2）HashMap 是非线程安全的。
         *
         * 5.key && value 能否为空
         * （1）Hashtable 的 key 不能为 null，value 也不能为 null，
         *  从 Hashtable 源码中的 put 方法看到，判断如果 value 为 null 就直接抛出空指针异常，
         *  在 put 方法中计算 key 的 hash 值之前并没有判断 key 为 null 的情况，如果 key 为空，也会抛出空指针异常。
         * （2）HashMap 的 key 和 value 都可以为 null。
         *  在计算 hash 值的时候，有判断，如果key==null ，则其 hash= 0 （注意 ：HashMap中，只能够有唯一的 key == null）
         *  至于 value 是否为 null，根本没有判断过。（HashMap中value是允许为null的;）
         *
         * 7. 所使用的hash值
         *  hash 值是 JDK 根据对象的地址或者字符串或者数字算出来的 int 类型的数值。
         *  然后再使用除留余数法来获得 对象 最终位置。
         *  除法运算是非常耗费时间的，效率很低。
         *  （注意 ：位运算，是所有运算中效率最高的;）
         *
         * （1）Hashtable 直接使用对象的 hash 值.
         * （2）HashMap 为了提高计算效率，将哈希表的大小固定为了 2 的幂次方，
         *  这样在取模预算时，只需要做位运算。位运算比除法的效率要高很多。
         *
         * 8. Hashtable、HashMap 都使用了 Iterator。
         * Hashtable 还使用了Enumeration 的方式。
         *
         * 9.初始容量
         * （1）默认情况下，初始容量不同，Hashtable 的初始长度是 11，之后每次扩充容量变为之前的2n+1（n 为上一次的长度）
         * （2）HashMap 的初始长度为 16，之后每次扩充变为原来的两倍。
         *
         * 总结 ：
         * ===》
         * （1）考虑性能的话 ：Hashtable 是线程安全，推荐使用 HashMap 代替 Hashtable；
         * （2）考虑线程安全的话 ：如果需要线程安全高并发的话，推荐使用 ConcurrentHashMap 代替 Hashtable
         *
         */

        /**
         * hashMap的长度为啥是2的n次方呢？
         * 目的 ：
         * （要向hash表中去存储某个key-value键值对 时，需要根据hashcode去 确定key在hash表中位置;）
         * （1）为了能让 HashMap 存数据和取数据的效率高，尽可能地减少 hash 值的碰撞，
         * ===》 也就是说尽量把数据均匀分配，每个链表或者红黑树长度尽量相等。
         *
         * （2）核心 ：位运算，运算效率是远远高于其他运算的;
         * 取余（%）操作中,如果除数是 2 的幂次，则等价于与其除数减一的与（&）操作;
         * ===>
         * 前提 ：length 是 2 的 n 次方;
         * hash % length == hash & (length - 1)
         * 注意 ：采用二进制位操作 & ，相对于 % 能够提高运算效率。
         */
    }
}
